#include "http.h"
#include "lib/sockio.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define BUFSZ 4096

const char * header_get = "GET %s HTTP/1.0\r\n"
                          "Host: %s\r\n"
                          "Connection: close\r\n"
			  "\r\n"
;

int http_get(const char *_url, FILE *body, char **header)
{
  int fd, status = 0;
  char *url, *host, *path, *request_header, *response_header;
  size_t count = 0;
  int port = 80;
  size_t headerlen = 0;
  
  char *buffer = 0, *c;
  
  if (_url == NULL)
    return REQUEST_INVALID_URL;
  
  url = strdup(_url);
  
  path = index(url, '/');
  if (path != NULL)
  {
    *path = '\0';
    path++;
  }
  else
  {
    path = "/";
  }
  
  /* nesse ponto, a url ja esta encontrada */
  host = url;
 
  if ((c = rindex(host, ':')) != NULL)
  {
    port = atoi(c+1);
    *c = '\0';
    c = 0;
  }
    
  
  fd = sockopen(host, port, SOCKET_TCP);
  if (fd <= 0)
  {
    free(url);
    return fd;
  }
  
  /* faz o header */
  request_header = calloc(
    strlen(host) + strlen(path) 
    +strlen(header_get) + 1, 1
  );
  sprintf(request_header, header_get, path, host);
  
  headerlen = strlen(request_header);
  
  for (count = 0, status = 1;
       count < headerlen && status > 0;
       status = sockwrite(fd, request_header + count, headerlen - count), 
       count += status
  ); // { printf("s: %d %d\n", status, count); }
  
  /* leitura do response */
  buffer = calloc(1, BUFSZ);
  
  count = sockread(fd, buffer, BUFSZ);
  
  if (count == 0 || ((c = strstr(buffer, "\r\n\r\n")) == 0))
  {
    /* boom. nao foi encontrado header nos primeiros 4k */
    free(buffer);
    free(url);
    free(request_header);
    return REQUEST_INVALID_RESPONSE;
  }
  
  *c = '\0'; /* marca o fim do header */
  response_header = strdup(buffer); /* copia o header pra outro lugar */
  status = atoi(index(index(response_header, ' '), ' ')); /* calcula o status */
  
  if (status == 200)
  {
    c += 4; /* caminha ateh o comeco do buffer */
    fwrite(c, 1, count-(c-buffer), body); /* escreve o restante do buffer */
    
    /* le o resto */
    while ((count = sockread(fd, buffer, BUFSZ)) > 0)
    {
      fwrite(buffer, 1, count, body);
    }
  }
  
  free(buffer);
  free(url);
  free(request_header);
  
  if (header != NULL)
  {
    if (*header != NULL)
      free(*header);
    *header = response_header;
  }
  else
  {
    free(response_header);
  }

  return status;
}
